﻿using System.Collections.Generic;

namespace Conv
{
    public class ConvNet90
    {
        Layer _inputLayer;
        private ConvolutinalLayer H1;
        private SubsamplingLayer H2;
        private ConvolutinalLayer H3;
        private SubsamplingLayer H4;
        private FullConnectedLayer _outLayer;
        private ITeacheble[] _layers;
        public ConvNet90()
        {
            //1.7159*Math.Tanh(x*2/3);
            //-1.44*Math.Tanh(2*x/3)*Math.Tanh(2*x/3)+1.44
            _inputLayer = new Layer(28,28);
            H1 = new ConvolutinalLayer(new List<Layer>(1) { _inputLayer },4,5);
            H2 = new SubsamplingLayer(H1.MapList,2);
            H3= new ConvolutinalLayer(H2.MapList,12,5);
            H4 = new SubsamplingLayer(H3.MapList,2);
            _outLayer = new FullConnectedLayer(H4.MapList,10);
            _layers = new ITeacheble[5];
            _layers[0] = H1;
            _layers[1] = H2;
            _layers[2] = H3;
            _layers[3] = H4;
            _layers[4] = _outLayer;
        }
        public int Process(double[,] inputArray)
        {
            _inputLayer.SetState(inputArray);
            for (int i = 0; i < _layers.Length; i++)
                _layers[i].Process();
            int number = 0;
            double max = -1;
            for (int i = 0; i < _outLayer.Neurons.Length; i++)
            {
                if (_outLayer.Neurons[i, 0].State > max)
                {
                    max = _outLayer.Neurons[i, 0].State;
                    number = i;
                }
            }
            return number;
        }
        public void Teach(int correct)
        {

            #region Deal With Out Layer

            for (int k = 0; k < 10; k++)
            {
                Neuron currentNeuron = _outLayer.Neurons[k, 0];
                if (k == correct)
                {
                    currentNeuron.Sigma = (1.0 - currentNeuron.State);//currentNeuron.Sigma = (1.7 - currentNeuron.State)
                }
                else
                {
                    currentNeuron.Sigma = (-1.0 - currentNeuron.State);//currentNeuron.Sigma = (-1.7 - currentNeuron.State);
                }
            }
            #endregion

            for (int i = _layers.Length - 1; i >= 0; i--)
                _layers[i].BackPropogate();

            for (int i = _layers.Length - 1; i >= 0; i--)
                _layers[i].UpdateWeight();
        }
    }
}